/*
 * NGramas64.h
 *
 *  Created on: 18/11/2014
 *      Author: juan manuel
 */

#ifndef NGRAMAS64_H_
#define NGRAMAS64_H_


#include <iostream>
#include <string>
#include <sstream>
#include <list>
#include <map>
#include <fstream>
#include <vector>
#include <set>
using namespace std;


#define NOMBRE_ARCHIVO_TRIGRAMAS "trigramas.txt"
#define SEPARADOR_PRIMERAS_PALABRAS 'P'
#define SEPARADOR_SEGUNDAS_PALABRAS 'S'
#define SEPARADOR_TERCERAS_PALABRAS 'T'
#define SEPARADOR_PALABRA_FRECUENCIA 'F'

struct sFreqArchivo{
	int indice;
	int frequencia;
	ofstream* archivo;
	ofstream* archivoDeApariciones;
};


//ESTE STRUCT VA A SER USADO PARA TENER UN DICCIONARIO INDICE-PALABRA-FREQ, ORDENADO POR INDICE
struct sPalabraYFrecuencia{
	string palabra;
	int frecuencia;
};














struct palabraYProbabilidad{
	string palabra;
	float probabilidad;
};

struct palabrasDeTrigrama{
	/*
	string segundaPalabra;
	string terceraPalabra;
	*/
	int segundaPalabra;
	int terceraPalabra;

};

struct comparadorDeTrigramas{
	bool operator()(const palabrasDeTrigrama trigrama1, const palabrasDeTrigrama trigrama2) const{

		if (trigrama1.segundaPalabra != trigrama2.segundaPalabra){
			return (trigrama1.segundaPalabra < trigrama2.segundaPalabra);
		}
		else{
			return (trigrama1.terceraPalabra < trigrama2.terceraPalabra);
		}
	}
};





struct datosDeUnaPAlabraDelDiccionario{
	int indice;
	int frequencia;
	set<int>* apariciones;
	//map<palabrasDeTrigrama,int,comparadorDeTrigramas>* segundaYTerceraPalabra;
	map<palabrasDeTrigrama,int,comparadorDeTrigramas> segundaYTerceraPalabra;
};















//Se agrega con el formato: indice palabra2 - indice palabra3
void agregarTrigrama(string palabra1, string palabra2, string palabra3);

//Si no esta, la agrega con frecuencia 0 y archivo = nullptr
void agregarPalabraAlDiccionario(string palabra);

/*Si no esta, la agrega con frecuencia 0 y archivo = nullptr
  Ademas le suma 1 a la frecuencia
*/
void agregarPalabraSueltaAlDiccionario(string palabra);

void agregarTrigramas(vector<string> &palabras);

/*Se guarda con el formato: indice - palabra - frecuencia - direccion
  La direccion creo que no va a ser necesario guardarla
*/
void guardarDiccionario();
void guardarTrigramasAparicionesYVaciarDatos();


void cargarDiccionarioAnterior();


void encontrarFrecuenciaPromedioDelDiccionario();
void reducirYGuardarDiccionario();
void filtrarArchivosDeApariciones();
void filtrarPorAparicionesONoApariciones();
//void mergearArchivosDeApariciones();
void mergearArchivosDeApariciones(string numero1, string numero2);




void mergearArchivosDeTrigramas(string numero1, string numero2);
void reducirArchivoDeTrigramas();
void filtrarArchivoDeTrigramas();//Se sacan los trigramas que tengan alguna palabra con freq<100
void cargarYGuardarDiccionarioFiltradoPorPalabra();












void cerrarArchivos();


void ordenarYReducirArchivoDeTrigramas(string palabraInicial);

//El formato final es: indice palabra2 - indice palabra3 - frecuencia
void guardarArchivoDeTrigramasReducido(map<palabrasDeTrigrama,int,comparadorDeTrigramas>* mapaDeTrigramas, string palabraInicial);

vector<palabraYProbabilidad> obtenerCandidatas(string palabra1, string palabra2);

size_t encontrarHueco(vector <string> palabras);


#endif
